import logging

from django.shortcuts import render
from elasticsearch.dsl import Q
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from search.documents import CourseDocument

# Create your views here.

logger = logging.getLogger("django")


class SearchView(APIView):

    def get(self, request):
        # 1:接受参数
        nav_name = request.query_params.get("nav_name")
        category_id = request.query_params.get("categoryId")
        price_range = request.query_params.get("price_range", "")

        sort_ord = request.query_params.get("sortord", "")

        keywords = request.query_params.get("keywords", "").strip()  # 去除前后空格

        page = int(request.query_params.get('page', 1))
        page_size = int(request.query_params.get("page_size", 10))
        if page < 1:
            page = 1
        if page_size < 1:
            page_size = 10
        if page_size > 50:
            page_size = 50  # 限制最大的条数

        # 计算起始位置
        start = (page - 1) * page_size

        if not any([nav_name, category_id, keywords]):
            return Response({"code": 0, "message": "导航名称和分类ID或者关键词至少提供一个"},
                            status=status.HTTP_400_BAD_REQUEST)

        # 构建搜索查询
        search = CourseDocument.search()
        queres = []
        if keywords:
            logger.info(f"按照这种关键词搜索[{keywords}]")
            # 构建多字段匹配查询
            multi_match_query = Q('multi_match', query=keywords,
                                  fields=[
                                      "course_name^3",  # 课程名称权重最高
                                      "brief^2",  # 课程简介权重其次
                                      "course_description",
                                      "outcomes",
                                      "teacher_name",
                                      "teacher_title",
                                      "category_names",
                                      "nav_names"
                                  ],
                                  type="best_fields",  # 使用最佳字段匹配
                                  minimum_should_match="75%",  # 至少匹配75%的词条
                                  )
            queres.append(multi_match_query)

        if nav_name:
            # 使用 match_phrase 精准匹配查询
            q = Q('match_phrase', nav_names=nav_name)
            queres.append(q)
        if category_id:
            q = Q('match_phrase', category_ids=str(category_id))
            queres.append(q)

        if price_range:
            if price_range in ['1', '2']:
                logger.info(f"按照这种价格区间[{price_range}]")
                course_type = int(price_range)
                queres.append(Q('term', course_type=course_type))

        # 组合查询条件(如果两个条件都存在, 使用AND关系)
        if len(queres) > 1:
            search = search.query('bool', must=queres)
        else:
            search = search.query(queres[0])

        if sort_ord:
            logger.info(f"按照这种排序方式[{sort_ord}]")
            if sort_ord == '1':
                search = search.sort("-pub_date")
            elif sort_ord == '2':
                search = search.sort("-students")
            elif sort_ord == '3':
                search = search.sort("price")
        # 获取总数
        total = search.count()
        # 设置分页参数
        search = search[start:start + page_size]
        # 执行搜索
        try:
            response = search.execute()
            logger.info(response)
            logger.info(type(response))

            results = []

            for hit in response:
                # 验证条件
                is_valid = True

                # 检查hit.nav_names 是否真的包含搜索词(额外验证)
                if nav_name:
                    nav_names_list = [name.strip() for name in hit.nav_names.split("|")]
                    is_valid = nav_name in nav_names_list

                if is_valid and category_id:
                    category_ids_list = [int(cid.strip()) for cid in hit.category_ids.split("|")]
                    is_valid = int(category_id) in category_ids_list

                if is_valid:
                    results.append({
                        "id": hit.course_id,
                        "course_img": hit.course_img,
                        "name": hit.course_name,
                        "brief": hit.brief,
                        "teacher": {
                            "name": hit.teacher_name,
                            "title": hit.teacher_title
                        },
                        "students": hit.students,
                        "lessons": hit.lessons,
                        "course_type": hit.course_type,
                        "course_type_text": "付费" if hit.course_type == 2 else "免费",
                        "original_price": str(hit.original_price),
                        "price": str(hit.price),

                    })
                    # (78 +10-1)//10

                    # 计算分页信息
                    """
                    这段代码用于计算总页数，其中：
total 是总数据条目数；
page_size 是每页显示的条目数；
(total + page_size - 1) // page_size 通过向上取整的方式计算总页数。
例如：若 total=105, page_size=10，则结果为 11 页。
                    """
            total_pages = (total + page_size - 1) // page_size
            has_next = page < total_pages
            has_previous = page > 1

            return Response({
                "code": 1,
                "message": "查询成功",
                "data": {
                    "count": total,
                    "next": has_next,
                    "previous": has_previous,
                    "results": results
                }

            })
        except Exception as e:
            logger.error(e)
            return Response({
                "code": 0,
                "message": f"搜索出错{str(e)}"})
